package controllers

import (
	"gin-elas-student-info/model"
	"gin-elas-student-info/repositories"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"net/http"
	"strconv"
)

type StudentController struct {
	repo *repositories.StudentRepository
}

func NewStudentController() *StudentController {
	return &StudentController{
		repo: &repositories.StudentRepository{},
	}
}

func (c *StudentController) CreateStudent(ctx *gin.Context) {
	var student model.Student
	if err := ctx.ShouldBind(&student); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	student.ID = uuid.New().String()
	if err := c.repo.Create(&student); err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	ctx.JSON(http.StatusCreated, gin.H{"student": student})
}

func (c *StudentController) GetStudent(ctx *gin.Context) {
	id := ctx.Param("id")
	student, err := c.repo.GetByID(id)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{"student": student})
}

func (c *StudentController) UpdateStudent(ctx *gin.Context) {
	id := ctx.Param("id")
	var student model.Student
	if err := ctx.ShouldBind(&student); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := c.repo.Update(id, &student); err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{"student": student})
}

func (c *StudentController) DeleteStudent(ctx *gin.Context) {
	id := ctx.Param("id")
	if err := c.repo.Delete(id); err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{"message": "Student deleted successfully"})
}

func (c *StudentController) SearchStudents(ctx *gin.Context) {
	query := ctx.Query("q")
	if query == "" {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "Query parameter is required"})
		return
	}
	students, err := c.repo.Search(query)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{"students": students})
}

func (c *StudentController) GetAllStudents(ctx *gin.Context) {
	// 获取分页参数，默认为第1页，每页10条
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	size, _ := strconv.Atoi(ctx.DefaultQuery("size", "10"))
	// 验证分页参数
	if page < 1 {
		page = 1
	}
	if size < 1 || size > 100 {
		size = 10
	}
	students, total, err := c.repo.GetAllStudents(page, size)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{"students": students, "total": total})

}

// 在 StudentController 结构体中添加新方法
func (c *StudentController) SearchByConditions(ctx *gin.Context) {
	// 从查询参数中获取条件
	conditions := map[string]interface{}{
		"name":       ctx.Query("name"),
		"grade":      ctx.Query("grade"),
		"major":      ctx.Query("major"),
		"class_name": ctx.Query("class_name"),
		"min_age":    ctx.Query("min_age"),
		"max_age":    ctx.Query("max_age"),
	}

	// 转换年龄为整数
	if minAge := conditions["min_age"]; minAge != "" {
		if age, err := strconv.Atoi(minAge.(string)); err == nil {
			conditions["min_age"] = age
		} else {
			conditions["min_age"] = nil
		}
	} else {
		conditions["min_age"] = nil
	}

	if maxAge := conditions["max_age"]; maxAge != "" {
		if age, err := strconv.Atoi(maxAge.(string)); err == nil {
			conditions["max_age"] = age
		} else {
			conditions["max_age"] = nil
		}
	} else {
		conditions["max_age"] = nil
	}

	students, err := c.repo.SearchByConditions(conditions)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, students)
}
